﻿using Elsa.Server.Api.Endpoints.WorkflowDefinitions;
using Newtonsoft.Json;
using static TyMES.ResponseModel.PassStationResponse;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using System.Linq;
using TyMES.Model;
using TyMES.Model.BaseInformation;
using TyMES.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using WalkingTec.Mvvm.Core;
using Aliyun.OSS;
using System.Net;
using TyMES.Model.Record;
using TyMES.Communication;
using Elsa.Models;
using Microsoft.AspNetCore.Mvc;

namespace TyMES.TemporaryClass
{
    public class StationServices
    {

        private readonly ILogger logger;
        private readonly IConfiguration configuration;
        private readonly HttpService httpService;
        private readonly IServiceScope serviceScope;
        private readonly WTMContext context;
        private string _LineCode;
        private string factoryCode;
        private string mesIP;
        private string mesPort;


        public StationServices(ILogger<PassStationService> logger, IConfiguration configuration, HttpService httpService, IServiceScopeFactory serviceScopeFactory)
        {
            this.logger = logger;
            this.configuration = configuration;
            this.httpService = httpService;
            this.serviceScope = serviceScopeFactory.CreateScope();
            var sp = this.serviceScope.ServiceProvider;
            this.context = sp.GetRequiredService<WTMContext>();
            this.factoryCode = configuration["FactoryCode"];
            this.mesIP = configuration["MESIP"];
            this.mesPort = configuration["MESPORT"];
            _LineCode = configuration["LineCode"];
        }


        public async Task<Route> GetRoute(string productcode, Order_Model order)
        {
            var route = await GetRouteFromLine(productcode,order.OrderCode);
            if (route == null)
            {
                //route = await GetRouteFromFactory("DM-2-TY", ordercode);  //实际
               var _route = await GetRouteFromFactory(_LineCode, order);
                if (_route == null)return null;
               _route.ProductCode=productcode;
               _route.Field5 = order.OrderCode;
               context.DC.Set<Route>().Add(_route);
               await context.DC.SaveChangesAsync();
               return _route;
            }
            return route;
        }

        
        private bool Need2Skip(string productcode)
        {

            return false;
        }

        public async Task<Route> GetRouteFromLine(string prouductcode,string ordercode)
        {
            var route = context.DC.Set<Route>().FirstOrDefault(x => x.ProductCode == prouductcode&&x.Field5==ordercode);
            return route;
        }

        public async Task<Route> GetRouteFromFactory(string linecode,Order_Model order)
        {
            var jsonresponse = await PostRoute2Factory(linecode,order);
            var response = ResolveRoute(jsonresponse);
            if (response != null&& response.data.Count>0)
            {
                Route route = new Route();
                route.RouteCode = response.data[0].routeNumber;
                route.RouteName = response.data[0].routeName;
                route.RouteVersion= response.data[0].routeVersion;
                foreach (var dataItem in response.data)
                {
                    var routeOperation = Map2RouteOperation(dataItem);

                    await AddorUpdateRouteOperationTask(routeOperation);
                }
                route.Field4 = response.data[response.data.Count - 1].operationCode;
                return route;
            }
            return null;
        }


        private async Task<string> PostRoute2Factory(string linecode,Order_Model order) 
        {
            string url = "http://" + mesIP + ":" + mesPort + configuration["ROUTEBOM"];

            var passStationRequest = new
            {
                serviceId = "Base005_Route",
                factoryCode = factoryCode,
                lineCode = linecode,
                orderCode = order.OrderCode,
                scheduleCode = order.ScheduleCode,
                updateTime = "",
                requestTime = ""
            };
            
            string postdata = JsonConvert.SerializeObject(passStationRequest);
            string value = await httpService.PostDataAsync(url, postdata);
            //logger.LogInformation("Base005_Route: " + postdata +"\n"+value);
            return value;
        }

        public RouteBOMResponse ResolveRoute(string jsonresponse)
        {
            RouteBOMResponse response = JsonConvert.DeserializeObject<RouteBOMResponse>(jsonresponse);
            if (response.success)
            {
                List<RouteOperation> routeOperations =
                    response.data.Select(dataItem => Map2RouteOperation(dataItem)).ToList();
            }

            return response;
        }

        public async Task AddRouteTask(Route route)
        {
            await context.DC.Set<Route>().AddAsync(route);
        }
        public async Task AddorUpdateRouteOperationTask(RouteOperation routeroperation)
        {
            var getroute = context.DC.Set<RouteOperation>().FirstOrDefault(x =>
                x.OrderCode == routeroperation.OrderCode &&
                x.RouteNumber==routeroperation.RouteNumber&&
                x.RouteVersion==routeroperation.RouteVersion&&
                x.OperationCode==routeroperation.OperationCode);
            if (getroute != null) getroute = routeroperation;
            else context.DC.Set<RouteOperation>().Add(routeroperation);
            await context.DC.SaveChangesAsync();
        }
        public RouteOperation Map2RouteOperation(OperationData data)
        {
            return new RouteOperation
            {
                LineCode=context.DC.Set<Order_Model>().SingleOrDefault(x => x.ScheduleCode==data.scheduleNumber).LineCode,
                LastOperationCode = data.lastOperationCode,
                NextNode = data.nextNode,
                NextOperationCode = data.nextOperationCode,
                NextOperationId = data.nextOperationId,
                OperationCode = data.operationCode,
                OperationId = data.operationId,
                OperationName = data.operationName,
                OrderCode = data.orderCode,
                OrderId = data.orderId,
                ParentOperationCode = data.parentOperationCode,
                ParentOperationId = data.parentOperationId,
                RouteName = data.routeName,
                RouteNumber = data.routeNumber,
                RouteVersion = data.routeVersion,
                ScheduleNumber = data.scheduleNumber,
                Sort = data.sort,
                AddTime = DateTime.TryParse(data.addTime, out var addTime) ? addTime : (DateTime?)null,
                EditTime = data.editTime
            };
        }
    }
}
